import 'package:flutter/services.dart';

import '../ding_rtc.dart';

class DingRtcEngine {

  static final DingRtcEngine _instance = DingRtcEngine._();
  factory DingRtcEngine() => _instance;

  DingRtcEngine._() {
    _channel.setMethodCallHandler((MethodCall call) async {
      switch (call.method) {
        case 'onError':
          int code = call.arguments['code'];
          String message = call.arguments['message'];
          for(DingRtcListener listener in _listeners) {
            listener.onError?.call(code, message);
          }
          break;
        case 'onJoinChannelResult':
          int result = call.arguments['result'];
          String channel = call.arguments['channel'];
          String userId = call.arguments['userId'];
          int elapsed = call.arguments['elapsed'];
          for(DingRtcListener listener in _listeners) {
            listener.onEnterRoom?.call(result, userId);
          }
          break;
        case 'onLeaveChannelResult':
          int result = call.arguments['result'];
          for(DingRtcListener listener in _listeners) {
            listener.onExitRoom?.call(result);
          }
          break;
        case 'onRemoteUserEnterRoom':
          String userId = call.arguments as String;
          for(DingRtcListener listener in _listeners) {
            listener.onRemoteUserEnterRoom?.call(userId);
          }
          break;
        case 'onRemoteUserLeaveRoom' :
          String userId = call.arguments['userId'] ?? call.arguments['uid'];
          DingRtcUserOfflineReason reason = DingRtcUserOfflineReason.values[call.arguments['reason']];
          for(DingRtcListener listener in _listeners) {
            listener.onRemoteUserLeaveRoom?.call(userId, reason);
          }
          break;
        case 'onRemoteStateUpdated':
          String userId = call.arguments['userId'] ?? call.arguments['uid'];
          DingRtcAudioTrack audio = DingRtcAudioTrack.values[call.arguments['audio']];
          DingRtcVideoTrack video = DingRtcVideoTrack.values[call.arguments['video']];
          for(DingRtcListener listener in _listeners) {
            listener.onRemoteStateUpdated?.call(userId, audio, video);
          }
          break;
        case 'onSnapshotComplete':
          String userId = call.arguments['userId'] ?? call.arguments['uid'];
          DingRtcVideoTrack track = DingRtcVideoTrack.values[call.arguments['videoTrack']];
          String path = call.arguments['filePath'];
          bool success = call.arguments['success'];
          for(DingRtcListener listener in _listeners) {
            listener.onSnapshotComplete?.call(userId, track, path, success);
          }
          break;
        default:
          print('[DingRtcEngine] ${call.method} not implement');
          break;
      }
    });
  }

  final MethodChannel _channel = const MethodChannel('ding_rtc_engine');
  final List<DingRtcListener> _listeners = [];
  _rtcLog(msg) {
    print('[DingRtcEngine] $msg');
  }

  Future<void> setLogLevel(DingRtcLogLevel level) {
    return _channel.invokeMethod('setLogLevel', level.value);
  }

  Future<void> initEngine([String extra = '']) {
    return  _channel.invokeMethod('initEngine',  extra);
  }

  Future destroyEngine() {
    return  _channel.invokeMethod('destroyEngine');
  }

  Future enterRoom(DRTCParams param) {
    return _channel.invokeMethod('enterRoom', param.toJson());
  }

  Future exitRoom(){
    return _channel.invokeMethod('exitRoom');
  }

  /// 开启/关闭麦克风
  Future muteLocalAudio(bool mute) {
    return _channel.invokeMethod('muteLocalAudio', mute);
  }
  /// 开启/关闭摄像头
  Future enableLocalVideo(bool enable) {
    return _channel.invokeMethod('enableLocalVideo', enable);
  }
  /// 开启/关闭扬声器
  Future enableSpeakerphone(bool enable) {
    return _channel.invokeMethod('enableSpeakerphone', enable);
  }
  Future switchCamera() {
    return _channel.invokeMethod('switchCamera');
  }

  ///[isFrontCamera] 在鸿蒙NEXT系统上无效，默认为前置摄像头
  Future startLocalPreview(int viewId,[bool isFrontCamera = true]) {
    return _channel.invokeMethod('startLocalPreview', {'front': isFrontCamera, 'viewId': viewId});
  }

  Future startRemoteView(String userId,  int viewId) {
    _rtcLog("startRemoteView userId: $userId viewId: $viewId");
    // if (TRTCPlatform.isMacOS || TRTCPlatform.isWindows) {
    //   await TRTCMethodChannel().startRemoteView(userId, streamType, viewId);
    //   return;
    // }
    if (!DingRtcVideoView.containsViewId(viewId)) {
      _rtcLog("startRemoteView fail, viewId does not exist");
      return Future.value(false);
    }
    return _channel.invokeMethod('startRemoteView', {'userId': userId,  'viewId': viewId});
  }

  Future stopAllRemoteView() {
    return _channel.invokeMethod('stopAllRemoteView');
  }


  void registerListener(DingRtcListener func) {
    _listeners.add(func);
  }

  void unRegisterListener(DingRtcListener? func) {
    _listeners.remove(func);
  }

  ///对指定用户的视频进行截图，生成一张JPG格式的图片，并保存至指定的路径 xxx.jpg
  Future snapshotVideo(String userId, String path,[bool isScreen = false]) {
    return _channel.invokeMethod('snapshotVideo', {'userId': userId, 'path': path, 'isScreen': isScreen});
  }

}